/* ----------------------------------------------------------------------- *
 *                                                                         *
 *                Ecole des Mines de Nantes - OSE OSM 2012                 *
 *                                                                         *
 * ----------------------------------------------------------------------- * 
 *
 * File:     utils/Utils.h
 * Version:  1.0
 * Created:  01:37 01/17/2012
 * Modified: 01:37 01/17/2012
 * Author:   Léopold Houdin
 * Description:
 *
 * ----------------------------------------------------------------------- */

#ifndef UTILS_H
#define UTILS_H

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

namespace pud
{

  /**
   * This class contains several static functions used in different plugins.
   */
  class Utils
  {
  public:
    /**
     * Returns a string that contains the path to the given file in the given directory.
     */
    static std::string
    fileInDirectory( const std::string& dir, const std::string& filename )
    {
      return dir+filename;
    }

    /**
     * Returns a char buffer with the value of the given unsigned.
     * The length of the return buffer is 2.
     */
    static char*
    unsignedToChar( const unsigned& u )
    {
      char* ret = new char[2];

      ret[0] = ( char ) ( u >> 4 );
      ret[1] = ( char ) u;

      return ret;
    }

    /**
     * Returns the unsigned value of a char buffer.
     * The length of the given buffer should be 2.
     */
    static unsigned
    charToUnsigned( const char* c )
    {
      return ( c[0] << 4 ) | c[1];
    }

    /*
    static std::vector< std::string >
    splitString( const std::string& str, const std::string& sep )
    {
      size_t n_pos = 0, p_pos = 0, size = sep.length();
      std::vector< std::string > ret;

      while( ( n_pos = str.find( sep, p_pos ) ) != std::string::npos )
        {
          ret.push_back( str.substr( p_pos, n_pos-p_pos ) );
          p_pos = n_pos+size;
        }
      ret.push_back( str.substr( p_pos, n_pos-p_pos-size ) );

      return ret;
    }

    static bool
    writeAllBytes( std::ofstream& filestream, std::string& toWrite )
    {
      int length = toWrite.length();

      if( !filestream.is_open() )
        return false;

      filestream.seekp( std::ios::beg );
      for( int i = 0; i < toWrite.length() ; i++ )
        filestream.put( toWrite[ i ] );

      return true;
    }

    static bool
    readAllBytes( std::ifstream& filestream, std::string& result )
    {
      int length;
      char* buffer;

      if( !filestream.is_open() )
        return false;

      filestream.seekg( 0, std::ios::end );
      length = filestream.tellg();
      filestream.seekg( 0, std::ios::beg );

      buffer = new char[ length ];
      filestream.read( buffer, length );

      result.assign( buffer );
      delete buffer;

      return true;
    }
     */
  };

  /**
   * This class is used for writing and reading data in files.
   */
  class FileStream : public std::fstream
  {
  public:
    // Parent class
    typedef std::fstream super;

    /**
     * Parameterized constructor.
     * Constructs a FileStream with the given file and the given open mode.
     */
    FileStream( const std::string filename, ios_base::openmode mode = ios_base::in | ios_base::out ) :
      m_filename( filename ), m_mode( mode | ios_base::binary )
    {
    }

    /**
     * Opens the file.
     * Returns true if the file has been successfully opened, false otherwise.
     */
    bool
    open( )
    {
      super::open( m_filename.c_str(), m_mode );
      return this->is_open();
    }

  protected:
    std::string m_filename;
    ios_base::openmode m_mode;
  };
}

#endif // UTILS_H

